import {validate, constraints_ActionItem, constraints_ActionNote} from '../untils/validate'

//const graphqlServerURL = 'http://localhost:4000/graphql';
const graphqlServerURL = 'https://project-hunter-nbrekdfyoz.now.sh/graphql';
const pageLength = 5;

/**
 * [action creator - show/hide the Action Item Edit panel]
 * @param  {[boolean]} showPanel [indicate if the panel should display]
 * @param  {[object]} formData [preset the form inputs, default to blank]
 */
export const actionItem_ShowEditPanel = (showPanel, formData) => ({
  type: 'PANEL_ACTIONITEM_DISPLAY',
  status: showPanel?'edit':'',
  formData: formData
});

/**
 * [action creator - show/hide the Action Note Edit panel]
 * @param  {[boolean]} showPanel [indicate if the panel should display]
 * @param  {[object]} formData [preset the form inputs, default to blank]
 */
export const actionNote_ShowEditPanel = (showPanel, formData) => ({
  type: 'PANEL_ACTIONNOTE_DISPLAY',
  status: showPanel?'edit':'',
  formData: formData
});

/**
 * [action creator - Action Item Panel - submit the form]
 * @return {[thunk]}   [ validate the form and submit it ]
 */
export const actionItem_FormSubmit = () => (dispatch, getState) => {
  dispatch(actionItem_WebRequestStatus('RequestStart'));
 
  // NO CHANGING STATE HERE, JUST READ STATE !!!
  let rv = getState();
  let thisReport = rv['actionReport']['actionItemReport'];
  let newActionItemDetail = thisReport['formData']['actionItemForm']['data'];
  let validationResults = validate(newActionItemDetail, constraints_ActionItem);

  if (!!validationResults) {
    let message = {
      'warning': [],
    };
    for(let attr in validationResults){
      message['warning'].push(validationResults[attr])
    }
    dispatch(actionItem_WebRequestStatus('RequestEnd', {
      data: null,
      message: message, 
      success: 0,
    }));
  }else{
    /* validation succeed, submit the form to server */
    let query;
    let pageIndex = 0;
    if (newActionItemDetail.id !== undefined) {
      /* edit mode */
      query =`
        mutation {
          updateActionItem( 
            id: "${newActionItemDetail.id}",
            input: {
              actionItem: "${newActionItemDetail.actionItem}",
              associatedSupplier: "${newActionItemDetail.associatedSupplier}",
              status: ${newActionItemDetail.status},
              dueDate: "${newActionItemDetail.dueDate}",
              respPerson: "${newActionItemDetail.respPerson}"
            }
          ){
            id
          }
        }
      `;
      pageIndex = thisReport.pageIndex;
    }else{
      /* add mode */
      query =`
        mutation {
          addActionItem( 
            input: {
              actionItem: "${newActionItemDetail.actionItem}",
              associatedSupplier: "${newActionItemDetail.associatedSupplier}",
              status: ${newActionItemDetail.status},
              dueDate: "${newActionItemDetail.dueDate}",
              respPerson: "${newActionItemDetail.respPerson}"
            }
          ){
            id
          }
        }
      `;
      pageIndex = Math.floor( (thisReport.dataCount + 1) / thisReport.pageLength);
    }


    fetch(graphqlServerURL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
      body: JSON.stringify({
        query,
      })
    })
    .then(res => res.json())
    .then(res => {
      /* reload the data */
      dispatch(actionItem_fetchActionItems(pageIndex));
      /*hide the edit panel */
      dispatch(actionItem_ShowEditPanel(false));
    })
    .catch(error => {
      dispatch(actionItem_WebRequestStatus('RequestEnd', {
        data: null,
        message: {
          error: [
            [error],
          ],
        }, 
        success: 0
      }));
    })
  }
};

/**
 * [action creator - Action Note Panel - submit the form]
 */
export const actionNote_FormSubmit = () => (dispatch, getState) => {
  dispatch(actionNote_WebRequestStatus('RequestStart'));

  // NO CHANGING STATE HERE, JUST READ STATE !!!
  let rv = getState();
  let thisReport = rv['actionReport']['actionNoteReport'];
  let newActionNoteDetail = rv['actionReport']['actionNoteReport']['formData']['actionNoteForm']['data'];
  let validationResults = validate(newActionNoteDetail, constraints_ActionNote);

  if (!!validationResults) {
    let message = {
      'warning': [],
    };
    for (let attr in validationResults) {
      message['warning'].push(validationResults[attr])
    }
    dispatch(actionNote_WebRequestStatus('RequestEnd', {
      data: null,
      message: message,
      success: 0,
    }));
  } else {
    /* validation succeed, submit the form to server */
    let query;
    let pageIndex = 0;
    if (newActionNoteDetail.id !== undefined) {
      /* edit mode */
      query = `
        mutation {
          updateActionNote( 
            id: "${newActionNoteDetail.id}",
            input: {
              note: "${newActionNoteDetail.note}",
              updateBy: "${newActionNoteDetail.updateBy}",
              createDate: "${newActionNoteDetail.createDate}"
            }
          ){
           id
          }
        }
      `;
      pageIndex = thisReport.pageIndex;
    }else{
      /* add mode */
      query = `
        mutation {
          addActionNote( 
            input: {
              note: "${newActionNoteDetail.note}",
              updateBy: "${newActionNoteDetail.updateBy}",
              createDate: "${newActionNoteDetail.createDate}"
            }
          ){
           id
          }
        }
      `;
      pageIndex = Math.floor( (thisReport.dataCount + 1) / thisReport.pageLength);
    }

    fetch(graphqlServerURL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
      body: JSON.stringify({
        query,
      })
    })
    .then(res => res.json())
    .then(res => {
      /*reload the data*/
      dispatch(actionNote_fetchActionNotes(pageIndex));
      /* hide the edit panel */
      dispatch(actionNote_ShowEditPanel(false));
    })
    .catch(error => {
      dispatch(actionNote_WebRequestStatus('RequestEnd', {
        data: null,
        message: {
          error: [
            [error],
          ],
        },
        success: 0
      }));
    })
  }
};


/**
 * [action creator - Action Item Edit inputs elem change]
 * @param  {[type]} formData [changed elem k-v object, will be merged into state]
 */
export const actionItem_FormChange = (formData) => ({
  type: 'PANEL_ACTIONITEM_FORM_CHANGE',
  formData: formData,
});

/**
 * [action creator - Action Item Edit inputs elem change]
 * @param  {[type]} formData [changed elem k-v object, will be merged into state]
 */
export const actionNote_FormChange = (formData) => ({
  type: 'PANEL_ACTIONNOTE_FORM_CHANGE',
  formData: formData,
});

/**
 * [action creater - Send web request and get current request status]
 * @param  {[string]} status [current web request status, enum in below values: RequestStart,RequestIn,RequestEnd] 
 * @param  {[object]} data [result data, include the result and other info (e.g. errors)]
 * @return {[object]}        [an new action]
 */
export const actionItem_WebRequestStatus = (status, result) => ({
  type: 'PANEL_ACTIONITEM_REQUEST',
  status: status,
  result: result,
});

/**
 * [action creater - Send web request and get current request status]
 * @param  {[string]} status [current web request status, enum in below values: RequestStart,RequestIn,RequestEnd] 
 * @param  {[object]} data [result data, include the result and other info (e.g. errors)]
 * @return {[object]}        [an new action]
 */
export const actionNote_WebRequestStatus = (status, result) => ({
  type: 'PANEL_ACTIONNOTE_REQUEST',
  status: status,
  result: result,
});


/**
 * [action creater - Load initial action item data onload]
 * @return {[thunk]} [will do fetch in Promise]
 */
export const actionItem_fetchActionItems = (pageIndex) => (dispatch, getState) => {
  dispatch(actionItem_WebRequestStatus('RequestStart'));

  /* CANNOT USE pageIndex outside return, MUST USE PageIndex in returned Promise, see below */
  return fetch(graphqlServerURL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify({
      query: `{
        getActionItems(page: ${pageIndex}) {
          dataCount
          pageIndex
          pageLength
          actionItems{
            id
            actionItem
            respPerson
            dueDate
            associatedSupplier
            status
          }
        }
      }`,
    })
  })
  .then(res => res.json())
  .then(res => {
    dispatch(actionItem_WebRequestStatus('RequestEnd', {
      data: res.data.getActionItems.actionItems,
      dataCount: res.data.getActionItems.dataCount,
      pageLength: res.data.getActionItems.pageLength,
      pageIndex: res.data.getActionItems.pageIndex,
      message: {}, 
      success: 1,
    }));
  })
  .catch(error => {
    dispatch(actionItem_WebRequestStatus('RequestEnd', {
      data: null,
      message: {
        error: [
          [error],
        ],
      }, 
      success: 0
    }));
  })
}

/**
 * [action creater - Load single action item data]
 * @return {[thunk]} [will do fetch in Promise]
 */
export const actionItem_loadActionItem = (id) => (dispatch, getState) => {
  dispatch(actionItem_WebRequestStatus('RequestStart'));

  return fetch(graphqlServerURL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify({
      query: `{
          getActionItem(id: ${id}) {
            id
            actionItem
            respPerson
            dueDate
            associatedSupplier
            status
          }
        }`,
    })
  })
  .then(res => res.json())
  .then(res => {
    dispatch(actionItem_WebRequestStatus('RequestEnd', {
      data: null,
      message: {}, 
      success: 1,
    }));
    dispatch(actionItem_ShowEditPanel(true, res.data.getActionItem));
  })
  .catch(error => {
    dispatch(actionItem_WebRequestStatus('RequestEnd', {
      data: null,
      message: {
        error: [
          [error],
        ],
      }, 
      success: 0
    }));
  })
}


/**
 * [action creater - load all paged action notes]
 * @return {[thunk]} [will do fetch in Promise]
 */
export const actionNote_fetchActionNotes = (pageIndex) =>  (dispatch, getState) => {
  dispatch(actionNote_WebRequestStatus('RequestStart'));

  return fetch(graphqlServerURL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify({
      query: `{
        getActionNotes(page: ${(Number.isInteger(pageIndex) && pageIndex >= 0) ? pageIndex : 0}) {
          dataCount
          pageIndex
          pageLength
          actionNotes {
            id
            note
            updateBy
            createDate
          }
        }
      }`,
    })
  })
  .then(res => res.json())
  .then(res => {
    dispatch(actionNote_WebRequestStatus('RequestEnd', {
      data: res.data.getActionNotes.actionNotes,
      dataCount: res.data.getActionNotes.dataCount,
      pageLength: res.data.getActionNotes.pageLength,
      pageIndex: res.data.getActionNotes.pageIndex,
      message: {}, 
      success: 1,
    }));
  })
  .catch(error => {
    dispatch(actionNote_WebRequestStatus('RequestEnd', {
      data: null,
      message: {
        error: [
          [error],
        ],
      }, 
      success: 0
    }));
  })
}


/**
 * [action creater - fetch single action note]
 * @return {[thunk]} [will do fetch in Promise]
 */
export const actionNote_loadActionNote = (id) =>  (dispatch, getState) => {
  dispatch(actionNote_WebRequestStatus('RequestStart'));

  return fetch(graphqlServerURL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify({
      query: `{
          getActionNote(id: ${id}) {
            id
            note
            updateBy
            createDate
          }
        }
      `,
    })
  })
  .then(res => res.json())
  .then(res => {
    dispatch(actionNote_WebRequestStatus('RequestEnd', {
      data: null,
      message: {}, 
      success: 1,
    }));
    dispatch(actionNote_ShowEditPanel(true, res.data.getActionNote));
  })
  .catch(error => {
    dispatch(actionNote_WebRequestStatus('RequestEnd', {
      data: null,
      message: {
        error: [
          [error],
        ],
      }, 
      success: 0
    }));
  })
}